from django.shortcuts import render
from django.http import HttpResponse
import time
from .fib_algorithm import *
from .fib_zkb import *

# 初始化方法、基本操作、空间效率字典
dic = {"迭代": ["加法", "线性"], "迭代改进": ["加法", "常数"], "递归": ["加法", "常数"], "Binet公式": ["乘法", "常数"], "矩阵": ["乘法", "常数"]}
# 用于存储计算结果的列表
results = []


# 实验1的首页
def experiment1(request):
    return render(request, 'fibo_app/experiment1.html')


# def index(request):
#     # 清空结果列表
#     results.clear()
#     return render(request, 'fibo_app/1.html', {'results': results})


# 1
def fibonacci_comparison(request):
    global dic
    if request.method == 'POST':  # 确保是 POST 请求
        n = int(request.POST.get('n'))  # 获取用户输入的数字
        results.clear()
        # 5 种算法计算斐波那契数
        methods = [
            ("迭代", calculate_fibonacci_number_iterative),
            ("迭代改进", calculate_fibonacci_number_iterative_imporve),
            ("递归", calculate_fibonacci_number_recursive),
            ("Binet公式", calculate_fibonacci_binet),
            ("矩阵", calculate_fibonacci_matrix)
        ]
        # 对每个算法进行计算并记录执行时间
        for method_name, method_func in methods:
            # 记录开始时间
            method_start_time = time.perf_counter()
            # 计算结果
            fibonacci_number, cnt = method_func(n)
            # 记录结束时间
            method_end_time = time.perf_counter()
            # 计算执行时间（微秒）
            method_execution_time = (method_end_time - method_start_time) * 1_000_000
            # 将结果添加到结果列表
            results.append({
                'number': n,
                'method': method_name,
                'result': fibonacci_number,
                'base_operate': dic[method_name][0],
                'base_operate_times': cnt,
                'execution_time': round(method_execution_time, 2),  # 保留两位小数
                'space_ef': dic[method_name][1]
            })

        # 返回渲染的 index.html，并传递结果
        return render(request, 'fibo_app/1.html', {'results': results})

    # 如果不是 POST 请求，重新渲染 index.html
    return render(request, 'fibo_app/1.html', {'results': results})


# 2
def max_fibonacci_iterative(request):
    """
    使用迭代法计算本机支持的最大整数能表示的最大斐波那契数
    并将结果渲染到 2.html 页面
    """
    results = []
    nums = []
    method = None
    method_dic = {'iterative': '迭代法', 'Binet': '公式法'}
    if request.method == 'POST':
        method = request.POST.get('method')
        results, nums = find_max(method)
    grouped_nums = [nums[i:i + 4] for i in range(0, len(nums), 4)]
    # 渲染到模板，并传递计算结果
    return render(request, 'fibo_app/2.html', {'result': results, 'grouped_nums': grouped_nums, 'method': method_dic.get(method, '')})


# 3
def max_fibonacci_recursive(request):
    result = None
    if request.method == 'POST':
        result = find_max_fibonacci_recursive()  # 调用递归方法

    return render(request, 'fibo_app/3.html', {'result': result})


# 4
# 视图函数
def check_recursive_1min(request):
    result = None

    if request.method == 'POST':
        # 计算第92个斐波那契数，并传递结果
        result = calculate_fibonacci_numbers(92, time_limit=5)  # 设置最大计算时间限制为60秒

    return render(request, 'fibo_app/4.html', {'result': result})


# 5
def max_fibonacci_recursive_30s(request):
    result = [41, 165580141, 24.23, 12.60]
    result = calculate_max_fibonacci()
    results = {
        'max_id': result[0],
        'fib_value': result[1],
        'time1': result[2],
        'time2': result[3]
    }
    return render(request, 'fibo_app/5.html', {'result': results})


# 6
def max_fibonacci_iterative_30s(request):
    result = [2256476, "17580681610475455034302938767011509445154100234038104861691923859442753837732177272998096855507465850718240844941804487853430105332740974143084160326739483881383139214217328081304245080001617777039536257361156873379212673082873327268951123710671083363830286232555200036145976866867652662192410945136021369149374073438143300479998951067961137568743887536857200769041887434030814847914278251220674040415169566351672986542898021197793795967683544838537698382352381013414216672826845597564836237867504432392817002474116882838802202600048834979556242991187831975301487694287289223209739620359801618764187897802707146142526655676574727970307556463984782119069289808836155108893783377110676949937641320599978299387713492593878073533548023075391765005541010420178228319689926836456435750686034542814522935696801501239192027960613947374558101797765444742483794764629886814305916570457417724306654678971068798702374627030643028854225660970602159544522699381966007120781642111590701587835847006387444801309335244059486036615880736539915379647575505818065691274287329573567830865595201945351411135446158166466294124809439550468512980532221240749466172939226052514478261682110094598089411986392160910073535302639664127318660118276183524014435222508452798611042185111752621706382877868154656890877197276322158412506942405185584096668638442500888637183109451710196129052021035168787187764712844368669496007442072788325057007954231745594730278862323861579762798465910060225446069603856967189868129241664939686104204419085878043980535004231503329080987517495961465343961522546389866648808151501327766531206562336371029815847599967064143037618960422869656045485344911813118684206465645923224916060782887065318856020441628548996900353526057190114197094715439680369637524461663635864253977706197601664461568827724562455656766631873923445883908972908476461964534416057225885569737954428726607858378593515290668068696437906661904097262782186825646100823110602362456379270729416624929067547799783566704812127209712499241387067231855529458696925132426252504428611047210364",29.98, 0.02]
    # result = calculate_max_fibonacci_iterative(timeout=30)
    results = {
        'max_id': result[0],
        'time1': result[2],
        'time2': result[3]
    }
    res = str(result[1])[:2048]
    return render(request, 'fibo_app/6.html', {'result': results, "res": res})


# 7
def min_fibonacci_error_free(request):
    """计算斐波那契数未出现误差时的最小斐波那契数，并显示误差"""
    result = None

    if request.method == 'POST':
        error_tolerance = float(request.POST.get('error_tolerance', 1e-2))  # 获取容忍误差，默认1e-2
        # 计算斐波那契数未出现误差时的最小值，以及误差信息
        n, real_value, binet_value, error = find_min_fibonacci_no_error(error_tolerance)

        # 准备计算结果
        result = {
            'n': n,
            'real_value': real_value,
            'binet_value': binet_value,
            'error': error,
            'error_tolerance': error_tolerance
        }

    # 渲染页面并返回结果
    return render(request, 'fibo_app/7.html', {'result': result})
